package com.gitee.huanminabc.jnetty.server.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

import java.net.URLDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author huanmin
 * @date 2023/12/1
 */

@Slf4j
public class HttpClientMessageHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    //最大线程数

    //单机最大并发数1024
    private final ExecutorService executor;

    private final HttpInterfaceHandler httpInterfaceHandler;

    public HttpClientMessageHandler(HttpInterfaceHandler httpInterfaceHandler, int maxThread) {
        this.httpInterfaceHandler = httpInterfaceHandler;
        executor = Executors.newFixedThreadPool(Math.max(maxThread, Runtime.getRuntime().availableProcessors() * 2));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
        // 获取请求方式 ,GET POST PUT DELETE
        HttpMethod method = req.method();
        String uri = req.uri();
        if ("/favicon.ico".equals(uri)) {
            return;
        }
        ByteBuf content = req.content().retain();
        executor.submit(() -> {
            //执行的开始时间
            long startTime = System.currentTimeMillis();
            String uriStr = "";
            try {
                //解码
                uriStr = URLDecoder.decode(req.uri(), "UTF-8");
                boolean go = httpInterfaceHandler.preHandler(ctx, req, req.headers().get(HttpHeaderNames.CONTENT_TYPE), method, uriStr, req.headers(), content);
                if (!go){
                    return;
                }
                httpInterfaceHandler.handler(ctx, req, req.headers().get(HttpHeaderNames.CONTENT_TYPE), method, uriStr, req.headers(), content);
            } catch (Throwable e) {
                httpInterfaceHandler.exceptionCaught(ctx, req, req.headers().get(HttpHeaderNames.CONTENT_TYPE), method, uriStr, req.headers(), content, e);
            } finally {
                //执行的结束时间
                long endTime = System.currentTimeMillis();
                //计算执行时间
                long executeTime = endTime - startTime;
                try {
                    httpInterfaceHandler.postHandler(ctx, req, req.headers().get(HttpHeaderNames.CONTENT_TYPE), method, uriStr, req.headers(), content, executeTime);
                } catch (Throwable e) {
                    log.error("",e);
                }
                //全部释放避免内存泄漏
                int refCnt = ReferenceCountUtil.refCnt(content);
                ReferenceCountUtil.release(content, refCnt);
                ctx.close();//和客户端断开连接,因为一个请求只会有一个连接
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("HttpClientMessageHandler exceptionCaught:{}", cause.getMessage());
        ctx.close();
    }

}
